﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint;

namespace CIB.AutoTitle.ServerCode
{
    public class DisableItemEvents : SPItemEventReceiver, IDisposable
    {
        private bool _EventStatus;

        public DisableItemEvents()
        {
            _EventStatus = base.EventFiringEnabled;
            base.EventFiringEnabled = false;
        }

        public void Dispose()
        {
            base.EventFiringEnabled = _EventStatus;
        }

    }

    public class FieldMask:IDisposable
    {
        private string _FieldInternalName;
        private string _MaskString;
        private SPListItem _Item;
        private Dictionary<string,string> _FieldsMasks = new Dictionary<string,string>();
        private bool ByDirectory;

        public FieldMask(SPListItem Item, string FieldInternalName, string MaskString)
        {
            this._Item = Item;
            this._FieldInternalName = FieldInternalName;
            this._MaskString = MaskString;
            this.ByDirectory = false;
        }

        public FieldMask(SPListItem Item, Dictionary<string, string> FieldsMasks)
        {
            this._Item = Item;
            this._FieldsMasks = FieldsMasks;
            this.ByDirectory = true;
        }
        public FieldMask(SPListItem Item)
        {
            this._Item = Item;
            this._FieldsMasks = this._Item.ParentList.RootFolder.CIBFilterProperties(Core.FieldMaskSuffix);
            this.ByDirectory = true;
        }

        private string GetUnMaskedValue(string MaskString)
        {
            var resultString = "";
            int startIndex1 = 0;
            int startIndex2 = 0;
            var nList = new List<string>();

            var SubString = "";
            startIndex1 = MaskString.IndexOf('[');
            if (startIndex1 != 0)
            {
                SubString = MaskString.Substring(0, startIndex1);
                resultString += SubString;
            }

            while (startIndex1 >= 0 && startIndex2 >= 0)
            {
                startIndex1 = MaskString.IndexOf('[', startIndex2);

                if (startIndex1 < startIndex2) continue;

                if ((startIndex1 - startIndex2) > 1)
                {
                    var sub = 1;
                    if (startIndex2 == 0)
                    {
                        sub = 0;
                    }
                    SubString = MaskString.Substring(startIndex2 + sub, startIndex1 - startIndex2 - sub);
                    resultString += SubString;
                }

                startIndex2 = MaskString.IndexOf(']', startIndex1);

                if (startIndex2 <= startIndex1) continue;

                SubString = MaskString.Substring(startIndex1 + 1, startIndex2 - startIndex1 - 1);

                var Field = this.TryGetByInternalName(SubString);
                if (Field == null) continue;
                var Value =this.GetValidatedString(Field, this._Item[Field.Id]);
                resultString += Value;
            }
            if (startIndex2 != MaskString.Length-1)
            {
                SubString = MaskString.Substring(startIndex2 + 1, MaskString.Length - startIndex2-1);
                resultString += SubString;
            }


            return resultString;
        }

        private void SetUnmasketValue(string FieldInternalName, string MaskString)
        {
            using (new DisableItemEvents())
            {
                var UnmaskedValue = this.GetUnMaskedValue(MaskString);
                var Field = this.TryGetByInternalName(FieldInternalName);
                this._Item[Field.Id] = UnmaskedValue;
                this._Item.Update();
            }

        }

        private string GetValidatedString(SPField Field, object Value)
        {
            var StringedValue = "";
            try
            {
                if (Field != null)
                {
                    var test1 = Field.Type;
                    var test2 = Field.TypeAsString;
                    var test3 = Field.InternalName;


                    var t = "";
                    switch (Field.Type)
                    {
                        case SPFieldType.DateTime:
                            if (Value == null)
                                return "";
                            var Format = Field.ParentList.RootFolder.CIBGetProperty(this._FieldInternalName + "_" + Core.DateFormatMaskSuffix);
                            StringedValue = ((DateTime)Value).ToString(Format);

                            break;
                        default:
                            StringedValue = Field.GetValidatedString(Value);
                            break;
                    }
                }
            }
            catch (Exception)
            {
                // Error in getting validated value
            }
            return StringedValue;
        }

        private SPField TryGetByInternalName(string InternalName)
        {
            SPField Field = null;

            try
            {
                Field = this._Item.ParentList.Fields.GetFieldByInternalName(InternalName);
            }
            catch (ArgumentException)
            {
                //There is no field with internal name
            }
            return Field;
        }

        public void Update()
        {
            if (this.ByDirectory)
            {
                foreach (var Mask in this._FieldsMasks)
                {
                    try
                    {
                        var FieldInternalName = Mask.Key.Replace("_" + Core.FieldMaskSuffix, "").Trim();
                        this._FieldInternalName = FieldInternalName;
                        this.SetUnmasketValue(FieldInternalName, Mask.Value);
                    }
                    catch (Exception)
                    {
                        // Unexpected error to pass through
                    }

                }
            }
            else
            {
                this.SetUnmasketValue(this._FieldInternalName, this._MaskString);
            }
        }

        public override string ToString()
        {
            return this.GetType().Name;
        }

        public void Dispose()
        {

        }

    }
}
